package testing;

import static org.junit.Assert.*;

import odor.Odor;

import org.junit.Test;

import util.Gaussian;
import util.SummedGaussian;
import util.Util;

public class OdorTest {

	@Test
	public void testOdor() 
	{
		Odor o = new Odor();
		
		assert(    o.getInputs() == null
				&& o.getMean() == Double.NaN
				&& o.getStandardDeviation() == Double.NaN
				&& o.equals(new Odor()));
	}

	@Test
	public void testGetMean() 
	{
		double[] zscores = {0.1, 1.0, 1.5, 2.0, 2.5, 3.0};
		
		SummedGaussian g = new SummedGaussian(zscores, Util.arraySum(zscores));
		Odor o = new Odor(zscores.length, g);
		
		assert(o.getMean() == g.getMean() && o.getMean() == Util.arrayMean(zscores));
	}

	@Test
	public void testGetStandardDeviation() 
	{
		double[] zscores = {0.1, 1.0, 1.5, 2.0, 2.5, 3.0};
		
		SummedGaussian g = new SummedGaussian(zscores, Util.arraySum(zscores));
		
		Odor o = new Odor(zscores.length, g);
		
		assert(o.getStandardDeviation() == g.getStandardDeviation() 
				&& o.getStandardDeviation() == Util.standardDeviation(zscores));
	}

	@Test
	public void testGenerateOdorBatteryIntIntInt() 
	{
		int numOdors = 5;
		int numInputCols = 10;
		double totalInputSum = 1000;
		double sigma = 25;
		
		Odor[] olist = Odor.generateOdorBattery(numOdors, numInputCols, totalInputSum, sigma);
		
		assert(    olist.length == numOdors
				&& checkOdorsStdev(olist, sigma)
				&& checkOdorsNumCols(olist, numInputCols)
				&& checkOdorsSum(olist, totalInputSum));
	}
	
	
	private boolean checkOdorsStdev(Odor[] list, double stdev)
	{
		if (list == null || list.length == 0) return false;
		
		for (Odor od : list)
		{
			if (od.getStandardDeviation() != stdev) return false;
		}
		
		return true;
	}
	
	private boolean checkOdorsNumCols(Odor[] list, int numCols)
	{
		if (list == null || list.length == 0) return false;
		
		for (Odor od : list)
		{
			if (od.getInputs().length != numCols) return false;
		}
		
		return true;
	}
	
	private boolean checkOdorsSum(Odor[] list, double sum)
	{
		if (list == null || list.length == 0) return false;
		
		for (Odor od : list)
		{
			if (Util.arraySum(od.getInputs()) != sum ) return false;
		}
		
		return true;
	}

	@Test
	public void testGetInputs() 
	{
		double[] zscores = {0.1, 1.0, 1.5, 2.0, 2.5, 3.0};
		SummedGaussian g = new SummedGaussian(zscores, Util.arraySum(zscores));
		
		Odor o1 = new Odor(zscores.length, g);
		
		assert( Util.arrayContains(zscores,o1.getInputs()));
	}

	@Test
	public void testEqualsObject() 
	{
		Odor o1 = new Odor();
		Odor o2 = new Odor();
		
		assert( o1.equals(o2));
		
		double[] zscores = {0.1, 1.0, 1.5, 2.0, 2.5, 3.0};
		SummedGaussian g = new SummedGaussian(zscores, Util.arraySum(zscores));
		
		o1 = new Odor(3, g);
		o2 = new Odor(3, g);
		
		assert (o1.equals(o2));
	}

	@Test
	public void testCompareTo() 
	{
		Odor o1 = new Odor();
		Odor o2 = new Odor();
		
		assert( o1.compareTo(o2) == Integer.MIN_VALUE);
		
		double[] zscores = {0.1, 1.0, 1.5, 2.0, 2.5, 3.0};
		SummedGaussian g = new SummedGaussian(zscores, Util.arraySum(zscores));
		
		o1 = new Odor(3, g);
		o2 = new Odor(3, g);
		
		assert ( o1.compareTo(o2) != 0 );
	}

}
